Vercel
Guides

Migrating from v1 to v2

Understand the major Platform API v2 changes before migrating from v1.

New API organization

Platform API v2 is organized around the resources your application renders and stores:

ResourceWhat it representsCommon endpoints
ChatsWorkspaces with metadata, privacy, Vercel project links, and current filesCreate Chat, Get Chat, List Chats, Update Chat
MessagesUser and assistant exchanges, including the agent traceSend Message, Get Messages, Get Message
FilesThe current source files in the VM-backed chatGet Chat Files, Update Chat Files, Download Chat Files
Previews and deploymentPreview access and production deployment for a chatGet Preview URL, Create Vercel Project, Deploy Chat
Tools and integrationsMCP servers and webhooks available to chatsMCP Servers, Webhooks

Messages contain ordered parts such as text, thinking, file reads, file edits, searches, bash commands, tool calls, and agent actions. This lets clients render the full agent trace without treating versions as the source of truth.

Usage is now returned directly on chat and message responses. This gives you real-time usage data as work completes instead of requiring a separate usage endpoint query after the fact.

What changed

Introducing organizations

v2 adds first-class multitenancy for platforms that serve v0 chats to their own customers. Instead of separating customers in your application code, isolate each one at the platform level with a Vercel Organization and per-customer child teams. Each child team gets its own scoped chats, API keys, usage, and limits. See Organizations.

Projects are no longer the organizing layer

v0 Projects are deprecated. In v2, use:

  • metadata on chats for project-like grouping, customer IDs, app IDs, favorite state, or internal routing.
  • vercelProjectId for the Vercel project attached to a chat.
  • The Vercel API for Vercel project operations such as environment variables, deployment lookup, deployment logs, and deletion.

v2 chats run on VMs

Platform API v2 is built around VM-backed chats. VMs are more capable than the old browser-based next-lite runtime used in v1: they can run a fuller project environment, support richer file operations, and provide a more direct path to Vercel projects, previews, and deployments.

Breaking change: Platform API v2 does not work with older Platform API v1 chats. We rebuilt v2 from the ground up to be compatible with more powerful primitives.

Sync, async, and streaming have explicit endpoints

v1 supported synchronous, asynchronous, and streaming behavior through the same core endpoints. In v2, those modes are split into explicit endpoint variants for the main agent workflows:

  • Sync endpoints block until the result is complete.
  • Async endpoints return immediately and let you poll the message or chat.
  • Streaming endpoints return Server-Sent Events so your UI can render progress as the agent thinks, edits files, uses tools, and reports usage.

Use streaming when you are building an interactive chat UI. Use async when your application triggers work in the background. Use sync when the caller can wait for the full result.

Versions are gone

v1 exposed versions as a first-class API concept. v2 removes version resources to simplify the model:

  • A chat is the durable workspace.
  • Messages are the history of what happened.

This means you no longer need to choose between chat IDs, project IDs, and version IDs for common workflows. Most operations now come down to operating on the chat itself, or interacting with it through messages.

Migrating existing v1 chats

Because v2 does not operate on v1 chats, migrate the underlying app state instead of the old chat record. This can be automated as long as your integration can choose the v1 chat version to carry forward.

  1. Choose the v1 chat/version state you want to preserve.
  2. Download that version as a ZIP with the v1 Download Version endpoint.
  3. Create a new v2 chat from that ZIP.
  4. Store the old v1 identifiers in v2 chat metadata if you need traceability.
  5. Move future messages, previews, deployments, and file updates to the new v2 chat.

Platform API v2 imports ZIP archives by URL. Use an HTTPS URL for larger archives, or a base64 data:application/zip URL for smaller archives. The Create Chat endpoint does not require a manual upload step, but it also does not accept multipart file uploads.

For smaller archives, download the v1 version ZIP and pass it to v2 as a data URL:

import { v0 } from 'v0-sdk'

const v1ChatId = 'chat_123'
const v1VersionId = 'version_456'

const zipResponse = await fetch(
  `https://api.v0.dev/v1/chats/${v1ChatId}/versions/${v1VersionId}/download?format=zip&includeDefaultFiles=true`,
  {
    headers: {
      Authorization: `Bearer ${process.env.V0_API_KEY}`,
    },
  },
)

if (!zipResponse.ok) {
  throw new Error('Failed to download v1 version files')
}

const zipBuffer = Buffer.from(await zipResponse.arrayBuffer())
const zipDataUrl = `data:application/zip;base64,${zipBuffer.toString('base64')}`

const chat = await v0.chats.create({
  type: 'zip',
  url: zipDataUrl,
  metadata: {
    migratedFrom: 'v1',
    v1ChatId,
    v1VersionId,
  },
})

For larger archives, upload the downloaded ZIP to your storage provider and pass the resulting HTTPS URL as url instead of a data URL.

After creating the v2 chat, use Send Message for new work.

Replacing v1 concepts

Replacing versions with chat state

In v2, the chat is the current app state. Most workflows that previously targeted a version now operate on the chat directly.

v1 version workflowv2 replacement
Get latest generated filesGet Chat Files
Download a versionDownload Chat Files
Edit generated files directlyUpdate Chat Files
Restore a previous generated stateRestore Message

Messages are still important for history and provenance. Use message parts to inspect what happened, and use Restore Message when you need to move the chat's files back to the state associated with a previous message.

Replacing projects with metadata

Use chat metadata for app-level organization.

const chat = await v0.chats.create({
  message: 'Create a sales dashboard',
  metadata: {
    workspaceId: 'workspace_123',
    appId: 'sales-dashboard',
  },
})

await v0.chats.update({
  chatId: chat.id,
  metadata: {
    favorite: 'true',
  },
})

Then use List Chats with metadata filters to build project-like views.

const chats = await v0.chats.list({
  metadata: {
    workspaceId: 'workspace_123',
  },
})

Use metadata for grouping and attribution. Do not use metadata as an access-control boundary; use team-scoped API keys for isolation. Learn more in Use the child-team key for chats.

Replacing environment variable workflows

Environment variables are attached to the Vercel project for a chat, not to a v0 Project.

  1. Use Get Chat to read vercelProjectId.
  2. If there is no vercelProjectId, call Create Vercel Project.
  3. Use the Vercel API to manage environment variables on that project.

For a complete walkthrough, see Environment Variables.

Replacing deployment workflows

Use Deploy Chat to deploy the current state of a chat.

const deployment = await v0.chats.deploy({
  chatId: 'chat_abc123',
})

For deployment lookup, logs, errors, and deletion, read the chat's vercelProjectId with Get Chat, then use the Vercel Deployments API.

Adding streaming to your UI

If your v1 integration already used streaming, migrate that workflow to the dedicated v2 streaming endpoint for the action. If it waited for a completed response, you can start with v2 sync endpoints and move to streaming when your UI is ready to render progress events.

On the server, forward the stream with toResponse():

// app/api/generate/route.ts
export async function POST(request: Request) {
  const { chatId, message } = await request.json()
  const result = await v0.messages.sendStream({ chatId, message })
  return result.toResponse()
}

On the client, wrap the response with readV0Stream. It reconstructs each snapshot for you, so update.parts is always the full, current state — no jsondiffpatch deltas to merge.

import { readV0Stream } from 'v0-sdk'

const result = readV0Stream(fetch('/api/generate', { method: 'POST', body }))

for await (const update of result.stream) {
  renderParts(update.parts)
}

Endpoint mapping

v1 workflowv2 workflow
Create a chatCreate Chat, Create Chat Streaming, or Create Chat Async
Send a messageSend Message, Send Message Streaming, or Send Message Async
Resume a streamResume Chat Stream
Resolve a taskResolve Task, Resolve Task Streaming, or Resolve Task Async
Get chat detailsGet Chat
List chatsList Chats
Update chat title, privacy, or metadataUpdate Chat
Favorite a chatStore favorite state in metadata with Update Chat
Restore files from a previous stateRestore Message
Deploy a chatDeploy Chat
Create a Vercel project for a chatCreate Vercel Project
Read preview access detailsGet Preview URL

Migration checklist

  • Create new v2 chats; do not reuse v1 chat IDs.
  • Decide how to seed v2 chats from existing v1 files or versions.
  • Replace version state with chat state and chat file workflows.
  • Replace v0 Project organization with chat metadata.
  • Move Vercel project operations to vercelProjectId plus the Vercel API.
  • Choose sync, async, or streaming endpoints for each workflow.
  • Update client rendering to consume message parts, not only final text.
  • Store old v1 IDs in metadata only for traceability.